/**
 * ********************************************************
 * <p>
 * Copyright (c) 2018 Baidu.com, Inc. All Rights Reserved
 * <p>
 * ********************************************************
 *
 * @date: 2018年8月21日
 * @author: wangzhihua02
 * @description: Blank
 */
package com.baidu.mpks.util;

import com.baidu.mpks.exception.BusinessException;
import com.fasterxml.jackson.databind.JsonNode;
import io.micrometer.core.instrument.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;


@Slf4j
public class ServletUtil {

    public static Integer getIntegerParam(HttpServletRequest request, String paramKey, Integer defaultValue) {
        Integer paramValue = null;
        try {
            paramValue = Integer.valueOf(getTrimStringParam(request, paramKey));
        } catch (Exception e) {
            // ignore
            log.error("" + e);
        }
        if (paramValue == null) {
            return defaultValue;
        }
        return paramValue;
    }

    public static Integer getIntegerParam(HttpServletRequest request, String paramKey) {
        Integer paramValue = null;
        try {
            paramValue = Integer.valueOf(getTrimStringParam(request, paramKey));
        } catch (Exception e) {
            // ignore
            log.error("");
        }
        return paramValue;
    }

    public static int getIntegerParamRequired(HttpServletRequest request, String paramKey) {
        try {
            return getIntegerParam(request, paramKey).intValue();
        } catch (Exception e) {
            throw new BusinessException("param [" + paramKey + "] is empty");
        }
    }

    public static Float getFloatParam(HttpServletRequest request, String paramKey) {
        Float paramValue = null;
        try {
            paramValue = Float.valueOf(getTrimStringParam(request, paramKey));
        } catch (Exception e) {
            // ignore
            log.error("");
        }
        return paramValue;
    }

    public static float getFloatParamRequired(HttpServletRequest request, String paramKey) {
        try {
            return getFloatParam(request, paramKey).intValue();
        } catch (Exception e) {
            throw new BusinessException("param [" + paramKey + "] is empty");
        }
    }

    public static Long getLongParam(HttpServletRequest request, String paramKey) {
        Long paramValue = null;
        try {
            paramValue = Long.valueOf(getTrimStringParam(request, paramKey));
        } catch (Exception e) {
            // ignore
            log.error("");
        }
        return paramValue;
    }

    public static long getLongParamRequired(HttpServletRequest request, String paramKey) {
        try {
            return getLongParam(request, paramKey).longValue();
        } catch (Exception e) {
            throw new BusinessException("param [" + paramKey + "] is empty");
        }
    }

    public static String getStringParam(HttpServletRequest request, String paramKey, String defaultParam) {
        String result = request.getParameter(paramKey);
        if (StringUtils.isEmpty(result)) {
            return defaultParam;
        }
        return result;
    }

    public static String getStringParam(HttpServletRequest request, String paramKey) {
        return request.getParameter(paramKey);
    }

    public static String getStringParamRequired(HttpServletRequest request, String paramKey) {
        String str = request.getParameter(paramKey);
        if (StringUtils.isEmpty(str)) {
            throw new BusinessException("param [" + paramKey + "] is empty");
        }
        return str;
    }

    public static String getTrimStringParam(HttpServletRequest request, String paramKey) {
        String value = request.getParameter(paramKey);
        return value == null ? null : value.trim();
    }

    public static String getTrimStringParamRequired(HttpServletRequest request, String paramKey) {
        String str = getTrimStringParam(request, paramKey);
        if (StringUtils.isEmpty(str)) {
            throw new BusinessException("param [" + paramKey + "] is empty");
        }
        return str;
    }

    public static String getTrimStringParamLengthBetween(HttpServletRequest request, String paramKey, int min,
                                                         int max) {
        String str = getTrimStringParam(request, paramKey);
        if (str != null && (str.length() < min || str.length() > max)) {
            throw new BusinessException("");
        }
        return str;
    }

    public static String getTrimStringParamRequiredLengthBetween(HttpServletRequest request, String paramKey, int min,
                                                                 int max) {
        String str = getTrimStringParamRequired(request, paramKey);
        if (str.length() < min || str.length() > max) {
            throw new BusinessException("");
        }
        return str;
    }

    public static List<String> getStringListParam(HttpServletRequest request, String key) {
        String listStr = getTrimStringParam(request, key);
        if (StringUtils.isEmpty(listStr)) {
            return Collections.emptyList();
        }
        List<String> ret = new ArrayList<>();
        for (String s : listStr.split(",")) {
            ret.add(s.trim());
        }
        return ret;
    }

    /**
     * 解析long列表参数：e.g. 10002,232,33324,1234
     *
     * @return 当参数为空时返回空list，否则返回Long型list @
     */
    public static List<Long> getLongListParam(HttpServletRequest request, String paramKey) {
        List<Long> list = new ArrayList<Long>();
        for (String longStr : getStringListParam(request, paramKey)) {
            try {
                list.add(Long.valueOf(longStr));
            } catch (Exception e) {
                throw new BusinessException(e);
            }
        }
        return list;
    }

    public static List<Integer> getIntegerListParam(HttpServletRequest request, String paramKey) {
        List<Integer> list = new ArrayList<Integer>();
        for (String intStr : getStringListParam(request, paramKey)) {
            try {
                list.add(Integer.valueOf(intStr));
            } catch (Exception e) {
                throw new BusinessException(e);
            }
        }
        return list;
    }

    public static Date getDateParam(HttpServletRequest request, String paramKey, SimpleDateFormat formatter,
                                    Date defaultDate) {
        String value = request.getParameter(paramKey);
        try {
            return formatter.parse(value.trim());
        } catch (ParseException | NullPointerException e) {
            return defaultDate;
        }
    }

    public static Date getJSONDateParam(JsonNode body, String paramKey, SimpleDateFormat formatter,
                                        Date defaultDate) {
        String value = body.get(paramKey).asText();
        try {
            return formatter.parse(value.trim());
        } catch (ParseException | NullPointerException e) {
            return defaultDate;
        }
    }

    public static void assertTrue(boolean value) {
        assertTrue(value, null);
    }

    public static void assertTrue(boolean value, String msg) {
        if (!value) {
            throw new BusinessException(msg);
        }
    }

    private static void setBeanProperties(Object object, String prop, Object value) {
        try {
            BeanUtils.setProperty(object, prop, value);
        } catch (Exception e) {
            // ignore
            log.error("");
        }
    }

    public static String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = ip.indexOf(",");
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            return ip;
        }
        return request.getRemoteAddr();
    }


    /**
     * name: getStringJSONParamRequired
     * reason: TODO
     * date: 2019年7月11日
     */
    public static String getStringJSONParamRequired(JsonNode body, String paramKey) {
        String str = body.get(paramKey).asText();
        if (StringUtils.isEmpty(str)) {
            throw new BusinessException("param [" + paramKey + "] is empty");
        }
        return str;

    }

    /**
     * name: getIntegerJSONParamRequired
     * reason: TODO
     * date: 2019年7月11日
     */
    public static Integer getIntegerJSONParamRequired(JsonNode body, String paramKey) {
        Integer val = body.get(paramKey).asInt();
        if (Integer.valueOf(val) == null) {
            throw new BusinessException("param [" + paramKey + "] is empty");
        }
        return val;

    }
//
//    @SuppressWarnings("unchecked")
//    public static Map<String, Object> getJSONParam(HttpServletRequest request) {
//        ObjectMapper mapper = new ObjectMapper();
//        // Read the request payload into a String
//        StringBuilder buffer = new StringBuilder();
//        Map<String, Object> jsonMap = new HashMap<>();
//        BufferedReader reader;
//        try {
//            reader = request.getReader();
//            String line;
//            while ((line = reader.readLine()) != null) {
//                buffer.append(line);
//            }
//            String data = buffer.toString();
//            jsonMap = mapper.readValue(data, Map.class);
//            // List<String> simQList = (List<String>)jsonMap.get("simQ");
//        } catch (IOException e) {
//            // TODO Auto-generated catch block
//            log.error("" + e);
//        }
//
//
//
//
//        return jsonMap;
//    }


    private static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");

    public static Date transferStrParamToDate(String param, Date defaultDate) {
        try {
            return dateFormatter.parse(param.trim());
        } catch (ParseException | NullPointerException e) {
            return defaultDate;
        }
    }

    public static String getUserAgent(HttpServletRequest request) {
        return request.getHeader("User-Agent");
    }

    public static String getReferer(HttpServletRequest request) {
        return request.getHeader("referer");
    }
}
